home *** CD-ROM | disk | FTP | other *** search
- /*
- * Window Maker window manager
- *
- * Copyright (c) 1997 Shige Abe and
- * Alfredo K. Kojima
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
- * USA.
- */
-
-
- #include "wconfig.h"
-
- #ifndef LITE
-
- #include <stdio.h>
- #include <stdlib.h>
- #include <string.h>
-
- #include <X11/Xlib.h>
- #include <X11/Xutil.h>
-
- #include "WindowMaker.h"
- #include "window.h"
- #include "actions.h"
- #include "client.h"
- #include "funcs.h"
- #include "stacking.h"
- #include "workspace.h"
- #include "framewin.h"
-
- /********* Global Variables *******/
- extern WPreferences wPreferences;
- extern Time LastTimestamp;
-
-
- /*
- * FocusWindow
- *
- * - Needs to check if already in the right workspace before
- * calling wChangeWorkspace?
- *
- * Order:
- * Switch to correct workspace
- * Unshade if shaded
- * If iconified then deiconify else focus/raise.
- */
- static void
- focusWindow(WMenu *menu, WMenuEntry *entry)
- {
- WWindow *wwin;
- WScreen *scr;
- int x, y, move=0;
-
- wwin = (WWindow*)entry->clientdata;
- scr = wwin->screen_ptr;
-
- wMakeWindowVisible(wwin);
-
- x = wwin->frame_x;
- y = wwin->frame_y;
-
- /* bring window back to visible area */
- move = wScreenBringInside(scr, &x, &y, wwin->frame->core->width,
- wwin->frame->core->height);
-
- if (move) {
- wWindowConfigure(wwin, x, y, wwin->client.width, wwin->client.height);
- }
- }
-
- /*
- *
- * Open switch menu
- *
- */
- void
- OpenSwitchMenu(WScreen *scr, int x, int y, int keyboard)
- {
- WMenu *switchmenu = scr->switch_menu;
- WWindow *wwin;
-
- if (switchmenu) {
- if (switchmenu->flags.mapped) {
- if (!switchmenu->flags.buttoned) {
- wMenuUnmap(switchmenu);
- } else {
- wRaiseFrame(switchmenu->frame->core);
-
- if (keyboard)
- wMenuMapAt(switchmenu, 0, 0, True);
- else
- wMenuMapCopyAt(switchmenu,
- x-switchmenu->frame->core->width/2, y);
- }
- } else {
- wMenuMapAt(switchmenu, x-switchmenu->frame->core->width/2, y,
- keyboard);
- }
- return;
- }
- switchmenu = wMenuCreate(scr,_("Windows"),True);
- scr->switch_menu = switchmenu;
-
-
- wwin = scr->focused_window;
- while (wwin) {
- UpdateSwitchMenu(scr, wwin, ACTION_ADD);
-
- wwin = wwin->prev;
- }
-
- if (switchmenu) {
- if (!switchmenu->flags.realized)
- wMenuRealize(switchmenu);
- wMenuMapAt(switchmenu, x-switchmenu->frame->core->width/2, y,
- keyboard);
- }
- }
-
-
- static int
- menuIndexForWindow(WMenu *menu, WWindow *wwin, int old_pos)
- {
- int idx;
-
- if (menu->entry_no == 0)
- return -1;
-
- #define WS(i) ((WWindow*)menu->entries[i]->clientdata)->frame->workspace
- if (old_pos >= 0) {
- if (WS(old_pos) >= wwin->frame->workspace
- && (old_pos == 0 || WS(old_pos-1) <= wwin->frame->workspace)) {
- return old_pos;
- }
- }
- #undef WS
-
- for (idx = 0; idx < menu->entry_no; idx++) {
- WWindow *tw = (WWindow*)menu->entries[idx]->clientdata;
-
- if (!IS_OMNIPRESENT(tw)
- && tw->frame->workspace > wwin->frame->workspace) {
- break;
- }
- }
-
- return idx;
- }
-
-
- /*
- * Update switch menu
- */
- void
- UpdateSwitchMenu(WScreen *scr, WWindow *wwin, int action)
- {
- WMenu *switchmenu = scr->switch_menu;
- WMenuEntry *entry;
- char title[MAX_MENU_TEXT_LENGTH+6];
- int i;
- int checkVisibility = 0;
-
- if (!wwin->screen_ptr->switch_menu)
- return;
- /*
- * This menu is updated under the following conditions:
- *
- * 1. When a window is created.
- * 2. When a window is destroyed.
- *
- * 3. When a window changes it's title.
- * 4. When a window changes its workspace.
- */
- if (action == ACTION_ADD) {
- char *t;
- int idx;
-
- if (wwin->flags.internal_window || WFLAGP(wwin, skip_window_list))
- return;
-
- if (wwin->frame->title)
- sprintf(title, "%s", wwin->frame->title);
- else
- sprintf(title, "%s", DEF_WINDOW_TITLE);
- t = ShrinkString(scr->menu_entry_font, title, MAX_WINDOWLIST_WIDTH);
-
- if (IS_OMNIPRESENT(wwin))
- idx = -1;
- else {
- idx = menuIndexForWindow(switchmenu, wwin, -1);
- }
-
- entry = wMenuInsertCallback(switchmenu, idx, t, focusWindow, wwin);
- free(t);
-
- entry->flags.indicator = 1;
- entry->rtext = wmalloc(MAX_WORKSPACENAME_WIDTH+8);
- if (IS_OMNIPRESENT(wwin))
- sprintf(entry->rtext, "[*]");
- else
- sprintf(entry->rtext, "[%s]",
- scr->workspaces[wwin->frame->workspace]->name);
-
- if (wwin->flags.hidden) {
- entry->flags.indicator_type = MI_HIDDEN;
- entry->flags.indicator_on = 1;
- } else if (wwin->flags.miniaturized) {
- entry->flags.indicator_type = MI_MINIWINDOW;
- entry->flags.indicator_on = 1;
- } else if (wwin->flags.focused) {
- entry->flags.indicator_type = MI_DIAMOND;
- entry->flags.indicator_on = 1;
- } else if (wwin->flags.shaded) {
- entry->flags.indicator_type = MI_SHADED;
- entry->flags.indicator_on = 1;
- }
-
- wMenuRealize(switchmenu);
- checkVisibility = 1;
- } else {
- char *t;
- for (i=0; i<switchmenu->entry_no; i++) {
- entry = switchmenu->entries[i];
- /* this is the entry that was changed */
- if (entry->clientdata == wwin) {
- switch (action) {
- case ACTION_REMOVE:
- wMenuRemoveItem(switchmenu, i);
- wMenuRealize(switchmenu);
- checkVisibility = 1;
- break;
-
- case ACTION_CHANGE:
- if (entry->text)
- free(entry->text);
-
- if (wwin->frame->title)
- sprintf(title, "%s", wwin->frame->title);
- else
- sprintf(title, "%s", DEF_WINDOW_TITLE);
-
- t = ShrinkString(scr->menu_entry_font, title,
- MAX_WINDOWLIST_WIDTH);
- entry->text = t;
-
- wMenuRealize(switchmenu);
- checkVisibility = 1;
- break;
-
- case ACTION_CHANGE_WORKSPACE:
- if (entry->rtext) {
- int idx = -1;
- char *t, *rt;
- int it, ion;
-
- if (IS_OMNIPRESENT(wwin)) {
- sprintf(entry->rtext, "[*]");
- } else {
- sprintf(entry->rtext, "[%s]",
- scr->workspaces[wwin->frame->workspace]->name);
- }
-
- rt = entry->rtext;
- entry->rtext = NULL;
- t = entry->text;
- entry->text = NULL;
-
- it = entry->flags.indicator_type;
- ion = entry->flags.indicator_on;
-
- wMenuRemoveItem(switchmenu, i);
-
- if (!IS_OMNIPRESENT(wwin) && idx < 0) {
- idx = menuIndexForWindow(switchmenu, wwin, i);
- }
-
- entry = wMenuInsertCallback(switchmenu, idx, t,
- focusWindow, wwin);
- free(t);
- entry->rtext = rt;
- entry->flags.indicator = 1;
- entry->flags.indicator_type = it;
- entry->flags.indicator_on = ion;
- }
- wMenuRealize(switchmenu);
- checkVisibility = 1;
- break;
-
-
- case ACTION_CHANGE_STATE:
- if (wwin->flags.hidden) {
- entry->flags.indicator_type = MI_HIDDEN;
- entry->flags.indicator_on = 1;
- } else if (wwin->flags.miniaturized) {
- entry->flags.indicator_type = MI_MINIWINDOW;
- entry->flags.indicator_on = 1;
- } else if (wwin->flags.shaded && !wwin->flags.focused) {
- entry->flags.indicator_type = MI_SHADED;
- entry->flags.indicator_on = 1;
- } else {
- entry->flags.indicator_on = wwin->flags.focused;
- entry->flags.indicator_type = MI_DIAMOND;
- }
- break;
- }
- break;
- }
- }
- }
- if (checkVisibility) {
- int tmp;
-
- tmp = switchmenu->frame->top_width + 5;
- /* if menu got unreachable, bring it to a visible place */
- if (switchmenu->frame_x < tmp - (int)switchmenu->frame->core->width) {
- wMenuMove(switchmenu, tmp - (int)switchmenu->frame->core->width,
- switchmenu->frame_y, False);
- }
- }
- wMenuPaint(switchmenu);
- }
-
-
-
- void
- UpdateSwitchMenuWorkspace(WScreen *scr, int workspace)
- {
- WMenu *menu = scr->switch_menu;
- int i;
- WWindow *wwin;
-
- if (!menu)
- return;
-
- for (i=0; i<menu->entry_no; i++) {
- wwin = (WWindow*)menu->entries[i]->clientdata;
-
- if (wwin->frame->workspace==workspace
- && !IS_OMNIPRESENT(wwin)) {
- if (IS_OMNIPRESENT(wwin))
- sprintf(menu->entries[i]->rtext, "[*]");
- else
- sprintf(menu->entries[i]->rtext, "[%s]",
- scr->workspaces[wwin->frame->workspace]->name);
- menu->flags.realized = 0;
- }
- }
- if (!menu->flags.realized)
- wMenuRealize(menu);
- }
-
-
- #endif /* !LITE */
-